﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Package_Carte;
using Package_Case;
using Package_Civilisation;
using Package_Civilisation.Package_Unite;
using Package_Jeu;
using System.Threading.Tasks;
using System.Timers;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.InteropServices;

using CivilisationIHM.Ressources;
using Wrapper;




namespace CivilisationIHM
{

    public partial class CarteIHM : Window
    {

    public Partie engine;
    public Carte map;

    public Queue<Joueur> FileJoueur;

    public List<Object> ListAutresChoix = new List<Object>();

    public Unite uniteCourante;
    public Ville villeCourante;
    public Joueur joueurCourant;



    public System.Drawing.Point pos;

    public Dictionary<Unite, Object> formUnite = new Dictionary<Unite, Object>();
    public Dictionary<Ville, Object> formVille = new Dictionary<Ville, Object>();
    public Dictionary<System.Drawing.Point, Object> formPosition = new Dictionary<System.Drawing.Point, Object>();
    
    public List<System.Drawing.Point> affichageCaseSelection = new List<System.Drawing.Point>();
    public List<System.Drawing.Point> affichageBrouillard = new List<System.Drawing.Point>();
        
    public static Unite uniteCompare;

    static String chemin = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"..\..\..\Images\";
    ImageBrush img_desert_vide = new ImageBrush(new BitmapImage(new Uri(chemin + "desert_vide.png")));
    ImageBrush img_plaine_vide = new ImageBrush(new BitmapImage(new Uri(chemin + "plaine_vide.png")));
    ImageBrush img_montagne_vide = new ImageBrush(new BitmapImage(new Uri(chemin + "montagne_vide.png")));
    ImageBrush img_desert_fer = new ImageBrush(new BitmapImage(new Uri(chemin + "desert_fer.png")));
    ImageBrush img_plaine_fer = new ImageBrush(new BitmapImage(new Uri(chemin + "plaine_fer.png")));
    ImageBrush img_montagne_fer = new ImageBrush(new BitmapImage(new Uri(chemin + "montagne_fer.png")));
    ImageBrush img_desert_fruit = new ImageBrush(new BitmapImage(new Uri(chemin + "desert_fruit.png")));
    ImageBrush img_plaine_fruit = new ImageBrush(new BitmapImage(new Uri(chemin + "plaine_fruit.png")));
    ImageBrush img_montagne_fruit = new ImageBrush(new BitmapImage(new Uri(chemin + "montagne_fruit.png")));
        /// <summary>
        /// Construction de la fenetre (référencé dans le App.xaml)
        /// </summary>
        public CarteIHM(Partie p)
        {
            InitializeComponent();
            engine = p;
            map = p.getCarte();
            FileJoueur = new Queue<Joueur>(engine.listJoueur);
            AutresChoix.SelectionChanged += new SelectionChangedEventHandler(AutresChoixEventSelection);
            BoolVisibility.Tag = false;
            Uri iconUri = new Uri(chemin + "king.ico");
            this.Icon = BitmapFrame.Create(iconUri);
            this.KeyDown += new KeyEventHandler(OnButtonKeyDown);
            uiScaleSlider.MouseDoubleClick +=
                new MouseButtonEventHandler(RestoreScalingFactor);
            
        }

        void RestoreScalingFactor(object sender, MouseButtonEventArgs args)
        {
            ((Slider)sender).Value = 1.0;
        }


        private void OnButtonKeyDown(object sender, KeyEventArgs e)
        {
            String key = e.Key.ToString();
            switch (key)
            {
                case "F":
                    cacherSelection();
                    tourSuivant();
                    updateUnitUI();
                    break;
                case "Z":
                    if (GestionUnite.Visibility == System.Windows.Visibility.Visible)
                    {
                        deplacerUnite(new System.Drawing.Point(uniteCourante.position.X, uniteCourante.position.Y - 1));
                    }
                    break;
                case "D":
                    if (GestionUnite.Visibility == System.Windows.Visibility.Visible)
                    {
                        deplacerUnite(new System.Drawing.Point(uniteCourante.position.X + 1, uniteCourante.position.Y));
                    }
                    break;
                case "Q":
                    if (GestionUnite.Visibility == System.Windows.Visibility.Visible)
                    {
                        deplacerUnite(new System.Drawing.Point(uniteCourante.position.X - 1, uniteCourante.position.Y));
                    }
                    break;
                case "S":
                    if (GestionUnite.Visibility == System.Windows.Visibility.Visible)
                    {
                        deplacerUnite(new System.Drawing.Point(uniteCourante.position.X, uniteCourante.position.Y + 1));
                    }
                    break;
                case "Escape":
                    MainWindow main = new MainWindow();
                    App.Current.MainWindow = main;
                    this.Close();
                    main.Show();
                    break;
                case "End":
                    sauvegarder();
                    break;
                default:
                    break;
            }
        }

        private void sauvegarder()
        {
            BinaryFormatter serialiser = new BinaryFormatter();
            System.IO.FileStream fichier = System.IO.File.Create("pierreLorilleux.test");
            serialiser.Serialize(fichier, engine);
            fichier.Close();

        }

        void AutresChoixEventSelection(object sender, SelectionChangedEventArgs e)
        {
            Object o = AutresChoix.SelectedItem;
            if (o is Unite)
            {
                Unite u = o as Unite;
                uniteCourante = u;
                afficherUniteCourante();
            }
            else if (o is Ville)
            {
                Ville v = o as Ville;
                villeCourante = v;
                afficherVilleCourante();
            }
        }

        /// <summary>
        /// Réaction à l'evt "la fenetre est construite" (référencé dans le MainWithEvents.xaml)
        /// </summary>
        /// <param name="sender">la fenetre </param>
        /// <param name="e"> l'evt : la fentere est construite</param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // on initialise la Grid (mapGrid défini dans le xaml) à partir de la map du modèle (engine)
            for (int c = 0; c < map.taille; c++)
            {
                mapGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50, GridUnitType.Pixel) });
            }
            for (int l = 0; l < map.taille; l++)
            {
                mapGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
                for (int c = 0; c < map.taille; c++)
                {
                    // dans chaque case de la grille on ajoute une tuile (logique) matérialisée par un rectangle (physique)
                    // le rectangle possède une référence sur sa tuile
                    var tile = map.getCase(c, l);
                    var element = createRectangle(c, l, tile);
                    mapGrid.Children.Add(element);
                    formPosition.Add(new System.Drawing.Point(c, l), element);
                }
            }
            updateUnitUI();
            tourSuivant();

            centerScrollViewer();
            
        }
        /////////////////////////////////////////////////////////////////
        //Création des formes
        /////////////////////////////////////////////////////////////////

        /// <summary>
        /// Création d'une elispe matérialisant une unité
        /// </summary>
        /// <param name="c"> Column </param>
        /// <param name="l"> Row </param>
        /// <param name="unite"> Tuile logique</param>
        /// <returns> Rectangle créé</returns>
        private Ellipse createEllipseUnite(int c, int l, Unite unite)
        {
            var ellispe = new Ellipse();
            ellispe.Height = 15;
            ellispe.Width = 15;


            ellispe.Fill = unite.civilisation.joueur.getColor();

            Grid.SetColumn(ellispe, c);
            Grid.SetRow(ellispe, l);

            ellispe.Tag = unite; // Tag : ref par defaut sur la tuile logique
            ellispe.MouseLeftButtonDown += new MouseButtonEventHandler(unite_MouseLeftButtonDown);
            return ellispe;
        }

        /// <summary>
        /// Création d'une croix matérialisant une ville
        /// </summary>
        /// <param name="c"> Column </param>
        /// <param name="l"> Row </param>
        /// <param name="ville"> Tuile logique</param>
        /// <returns> Croix créé</returns>
        private Ellipse createVille(int c, int l, Ville ville)
        {


            var circle = new Ellipse();
            circle.Height = 10;
            circle.Width = 30;
            Grid.SetColumn(circle, c);
            Grid.SetRow(circle, l);


            int j = ville.civilisation.joueur.numJoueur;
            switch (j)
            {
                case 1:
                    circle.Fill = Brushes.Red;
                    break;
                case 2:
                    circle.Fill = Brushes.SteelBlue;
                    break;
                case 3:
                    circle.Fill = Brushes.Pink;
                    break;
                default:
                    circle.Fill = Brushes.Snow;
                    break;
            }

            circle.Tag = ville; // Tag : ref par defaut sur la tuile logique
            circle.MouseLeftButtonDown += new MouseButtonEventHandler(ville_MouseLeftButtonDown);
            return circle;
        }

        private void ville_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var ellipse = sender as Ellipse;
            var ville = ellipse.Tag as Ville;

            if (joueurCourant != null && joueurCourant.civilisation.listeVille.Contains(ville))
            {

                villeCourante = ville;

                afficherVilleCourante();

                var selected = selectionVille.Tag;
                selectionVille.Tag = null;
                selectionVille.Tag = selected;
                getAutresChoixVille();
            }
            e.Handled = true;
        }
        //<summary>
        /// Création du rectangle matérialisant une tuile
        /// </summary>
        /// <param name="c"> Column </param>
        /// <param name="l"> Row </param>
        /// <param name="tile"> Tuile logique</param>
        /// <returns> Rectangle créé</returns>
        private Rectangle createRectangle(int c, int l, Case tile)
        {
            var rectangle = new Rectangle();
            rectangle.Width = 50;
            rectangle.Height = 50;
            if (tile is Desert)
                rectangle.Fill = img_desert_vide;
            if (tile is Plaine)
                rectangle.Fill = img_plaine_vide;
            if (tile is Montagne)
                rectangle.Fill = img_montagne_vide;
            if (tile is CaseFer)
            {
                if (((CaseSpeciale)tile).case_mere is Desert) rectangle.Fill = img_desert_fer;
                if (((CaseSpeciale)tile).case_mere is Montagne) rectangle.Fill = img_montagne_fer;
                if (((CaseSpeciale)tile).case_mere is Plaine) rectangle.Fill = img_plaine_fer;

            }
            if (tile is CaseFruit)
            {
                if (((CaseSpeciale)tile).case_mere is Desert) rectangle.Fill = img_desert_fruit;
                if (((CaseSpeciale)tile).case_mere is Montagne) rectangle.Fill = img_montagne_fruit;
                if (((CaseSpeciale)tile).case_mere is Plaine) rectangle.Fill = img_plaine_fruit;
            }
            // mise à jour des attributs (column et Row) référencant la position dans la grille à rectangle
            Grid.SetColumn(rectangle, c);
            Grid.SetRow(rectangle, l);
            rectangle.Tag = tile; // Tag : ref par defaut sur la tuile logique

            rectangle.Stroke = Brushes.Black;
            rectangle.StrokeThickness= 0;
            rectangle.Opacity = 0.3;
            // enregistrement d'un écouteur d'evt sur le rectangle : 
            // source = rectangle / evt = MouseLeftButtonDown / délégué = rectangle_MouseLeftButtonDown
            rectangle.MouseLeftButtonDown += new MouseButtonEventHandler(rectangle_MouseLeftButtonDown);
            rectangle.MouseRightButtonDown += new MouseButtonEventHandler(rectangle_MouseRightButtonDown);
            return rectangle;
        }

        private void rectangle_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            var rectangle = sender as Rectangle;
            var tile = rectangle.Tag as Case;

            int column = Grid.GetColumn(rectangle);
            int row = Grid.GetRow(rectangle);

            if (GestionUnite.Visibility == System.Windows.Visibility.Visible)
            {
                deplacerUnite(new System.Drawing.Point(column,row));
                centerScrollViewer();
            }
            
        }

        //////////////////////////////////////////////////////////////
        //Mouse_event
        //////////////////////////////////////////////////////////////
        /// <summary>
        /// Délégué : réponse à l'evt click gauche sur le rectangle, affichage des informations de la tuile
        /// </summary>
        /// <param name="sender"> le rectangle (la source) </param>
        /// <param name="e"> l'evt </param>
        void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var rectangle = sender as Rectangle;
            var tile = rectangle.Tag as Case;

            int column = Grid.GetColumn(rectangle);
            int row = Grid.GetRow(rectangle);
            
            pos = new System.Drawing.Point(column, row);

            Grid.SetColumn(selectionRectangle, column);
            Grid.SetRow(selectionRectangle, row);
            selectionRectangle.Tag = tile;
            selectionRectangle.Visibility = System.Windows.Visibility.Visible;

            if (joueurCourant != null)
            {
                joueurCourant.focus = new System.Drawing.Point(column, row);
                if (map.getUniteAmi(column, row, joueurCourant).Count != 0)
                {
                    cacheCaseSelection();
                    cacherSelection();

                    uniteCourante = map.getUniteAmi(column, row, joueurCourant)[0];

                    afficherUniteCourante();

                    //afficherUniteCourante();
                    GestionUnite.Visibility = System.Windows.Visibility.Visible;

                    getAutresChoixJoueur(); 
                }
                
                else if (map.getVille(column, row) != null)
                {
                    if (map.getVille(column, row).civilisation == joueurCourant.civilisation)
                    {
                        cacheCaseSelection();
                        cacherSelection();

                        villeCourante = map.getVille(column, row);

                        afficherVilleCourante();

                        //afficherUniteCourante();
                        GestionVille.Visibility = System.Windows.Visibility.Visible;

                        getAutresChoixVille();
                    }
                }
            }

            e.Handled = true;
        }

        void unite_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var ellipse = sender as Ellipse;
            var unite = ellipse.Tag as Unite;

            if (joueurCourant != null && joueurCourant.civilisation.listeUnite.Contains(unite))
            {

                cacheCaseSelection();
                cacherSelection();

                uniteCourante = unite;

                afficherUniteCourante();

                if (unite is Enseignant) montrerCaseSelection(suggestionVille(unite.position));
                GestionUnite.Visibility = System.Windows.Visibility.Visible;

                getAutresChoixJoueur();
            }
            e.Handled = true;
        }

        /// <summary>
        /// Délégué : réaction général à un clic sur la fenetre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectionRectangle.Visibility = System.Windows.Visibility.Collapsed;

        }


        //////////////////////////////////////////////////////////////
        //Button_action
        //////////////////////////////////////////////////////////////

        /// <summary>
        /// Délégué : réaction à l'evt : clic sur le bouton "prochain tour"
        /// </summary>
        /// <param name="sender"> le bouton "tour suivant" </param>
        /// <param name="e"></param>

        private void tourSuivant()
        {

            //On verifie que la partie n'est pas finie.
            if (engine.estFinie())
            {
                FinPartie fin = new FinPartie(engine.listJoueur.First<Joueur>());
                App.Current.MainWindow = fin;
                this.Close();
                fin.Show();
            }

            if (joueurCourant == null)
            {
                ActionButton.Content = "Fin du tour";
            }

            if (joueurCourant != null)
            {
                joueurCourant.civilisation.majMV();
                joueurCourant.civilisation.majPV();
                joueurCourant.civilisation.majVille();
            }


            cacheCaseSelection();
            joueurCourant = FileJoueur.Dequeue();
            while (!engine.listJoueur.Contains(joueurCourant))
            {
                joueurCourant = FileJoueur.Dequeue();

            }
            JoueurAffichage.Content = joueurCourant.pseudonyme;
            JoueurCouleur.Fill = joueurCourant.getColor();
            JoueurCouleur.Visibility = System.Windows.Visibility.Visible;
            JoueurAffichage.Tag = ListAutresChoix;
            FileJoueur.Enqueue(joueurCourant);

                
            
            updateUnitUI();
            centerScrollViewer();
        }


        public void centerScrollViewer()
        {
            if (joueurCourant != null)
            {
                double taille = engine.getCarte().taille;
                double uX = joueurCourant.focus.X;
                double uY = joueurCourant.focus.Y;

                double sX = Scroll.ScrollableWidth * uX / taille;
                double sY = Scroll.ScrollableHeight * uY / taille;

                Scroll.ScrollToVerticalOffset(sY);
                Scroll.ScrollToHorizontalOffset(sX);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            cacherSelection();
            tourSuivant();

            updateUnitUI();

        }

        private void deplacerUnite(System.Drawing.Point p)
        {
            if (p != null)
            {
                try
                {
                    uniteCourante.deplacer(p);
                    centerScrollViewer();

                }
                catch (InvalidOperationException)
                {
                    ShowError();
                }
                var selected = selectionUnite.Tag;
                selectionUnite.Tag = null;
                selectionUnite.Tag = selected;
                getAutresChoixJoueur();
                updateUnitUI();
                afficherUniteCourante();

            }
        }

        private void Action_Click_Unite(object sender, RoutedEventArgs e)
        {
            //selectionUniteSecondaire = null;
            if (uniteCourante is Etudiant)
            {
                int SuccesCombat=0;
            
                    if (pos != null)
                    {

                        try
                        {
                            SuccesCombat = ((Etudiant)uniteCourante).attaquer(pos);
                        }
                        catch (InvalidOperationException)
                        {
                            ShowError();
                        }
                        catch (FormatException)
                        {
                            ShowMessage("L'attaquant a été vaincu");
                            uniteCourante = null;
                            cacherSelection();
                            BoolVisibility.Tag = false;

                            updateUnitUI();

                        }
                        if (uniteCourante != null)
                        {
                            updateUnitUI();
                            afficherUniteCourante();
                        }

                    }

            }
            else if (uniteCourante is Enseignant)
            {
                    Enseignant enseignant = (Enseignant)uniteCourante;
                    try
                    {
                        
                        Ville creation = Enseignant.fonderVille(enseignant);
                        createVille(enseignant.position.X, enseignant.position.Y, creation);
                        villeCourante = creation;
                        uniteCourante = null;
                        cacherSelection();
                        BoolVisibility.Tag = false;

                        updateUnitUI();

                        afficherVilleCourante();
                        getAutresChoixVille();
                    }
                    catch (InvalidOperationException)
                    {
                        ShowError();
                    }
                    
             
            }
            


        }

        private String getUnite()
        {
            ListBoxItem o = (ListBoxItem)ChoixProductionVille.SelectedItem;

            if (o != null)
            {
                return o.Content.ToString();
            }
            else return "";
        }

        private void Action_Click_Ville(object sender, RoutedEventArgs e)
        {
            cacheCaseSelection();
            villeCourante.action = ChoixActionVille.SelectionBoxItem.ToString();
            if (villeCourante.action == "Passer le tour" | villeCourante.action == "Arreter production")
            {
            }
            else
            {
                String s = getUnite();
                if (s != "")
                {
                    villeCourante.productionUnite = getUnite();
                    villeCourante.enProduction = true;
                    villeCourante.verifierCoutUnite(getUnite());
                }
                
            }

            var selected = selectionVille.Tag;
            selectionVille.Tag = null;
            selectionVille.Tag = selected;

            updateUnitUI();

        }


        



        //////////////////////////////////////////////////////////////
        //Algo liés à la gestion des tour
        /////////////////////////////////////////////////////////

        /// <summary>
        /// </summary>
        /// 
        private void tourUnite()
        {
            // Peut lancer une exception
            //uniteCourante = FileUnite.Dequeue();//Peut lancer une exception

            GestionVille.Visibility = System.Windows.Visibility.Collapsed;



            GestionUnite.Visibility = System.Windows.Visibility.Visible;
            afficherUniteCourante();
        }

        private void tourVille()
        {

            cacherSelection();

            GestionUnite.Visibility = System.Windows.Visibility.Collapsed;

            GestionVille.Visibility = System.Windows.Visibility.Visible;


            //villeCourante = FileVille.Dequeue(); //Peut lancer une exception

            afficherVilleCourante();

        }

        /// <summary>
        /// Récupération de la position de l'unité (logique), mise à jour de l'ellipse (physique) matérialisant l'unité
        /// </summary>
        private void updateUnitUI()
        {

            int taille = mapGrid.Children.Count;
            Object[] children = new Object[taille];
            mapGrid.Children.CopyTo(children, 0);
            formUnite.Clear();
            formVille.Clear();

            foreach (var it in children)
            {
                if (it.GetType().Name.ToString() == "Ellipse")
                {
                    Ellipse r = (Ellipse)it;

                    mapGrid.Children.Remove(it as UIElement);
                    //now if we remove return then there will be enumerator error.


                }
            }
            List<Joueur> list = engine.listJoueur;

            foreach (Unite unite in Vue())
            {

                var element = createEllipseUnite(unite.position.X, unite.position.Y, unite);
                formUnite.Add(unite, element);
                mapGrid.Children.Add(element);
            }
            foreach (Joueur joueur in list)
            {

                foreach (Ville ville in joueur.civilisation.listeVille)
                {
                    var circle = createVille(ville.position.X, ville.position.Y, ville);
                    mapGrid.Children.Add(circle);
                    formVille.Add(ville, circle);

                }
            }
            montrerBrouillard();
        }
        private void afficherCase()
        {
            var Rec = (System.Windows.Shapes.Rectangle)formPosition[uniteCourante.position] as Rectangle;
            var Case = Rec.Tag as Case;


            int column = Grid.GetColumn(Rec);
            int row = Grid.GetRow(Rec);
            pos = new System.Drawing.Point(column, row);

            Grid.SetColumn(selectionRectangle, column);
            Grid.SetRow(selectionRectangle, row);
            selectionRectangle = Rec;
            selectionRectangle.Tag = Case;
            selectionRectangle.Visibility = System.Windows.Visibility.Visible;

            if (joueurCourant != null)
            {
                joueurCourant.focus = new System.Drawing.Point(column, row);
                if (map.getUniteAmi(column, row, joueurCourant).Count != 0)
                {
                    cacheCaseSelection();
                    cacherSelection();

                    uniteCourante = map.getUniteAmi(column, row, joueurCourant)[0];

                    afficherUniteCourante();

                    //afficherUniteCourante();
                    GestionUnite.Visibility = System.Windows.Visibility.Visible;

                    getAutresChoixJoueur();
                }
            }



        }
        private void afficherUniteCourante()
        {
            cacherSelectionUniteVille();
            if (uniteCourante != null)
            {
                var ellipse = (System.Windows.Shapes.Ellipse)formUnite[uniteCourante] as Ellipse;
                var unite = ellipse.Tag as Unite;


                int column = Grid.GetColumn(ellipse);
                int row = Grid.GetRow(ellipse);



                selectionUnite.Tag = uniteCourante;
                selectionUnite.Visibility = System.Windows.Visibility.Visible;
                ellipse.Stroke = new SolidColorBrush(Colors.AliceBlue);
                ellipse.StrokeThickness = 1;

                Grid.SetColumn(selectionUnite, column);
                Grid.SetRow(selectionUnite, row);


                var selected = selectionUnite.Tag;
                selectionUnite.Tag = null;
                selectionUnite.Tag = selected;


                GestionVille.Visibility = System.Windows.Visibility.Collapsed;
                GestionUnite.Visibility = System.Windows.Visibility.Visible;
                resetCombo();

            }
            if (uniteCourante is Enseignant) montrerCaseSelection(suggestionVille(uniteCourante.position));
            }
       
        private void cacherSelectionUniteVille()
        {
            if (uniteCourante != null)
            {
                var ellipse = (System.Windows.Shapes.Ellipse)formUnite[uniteCourante] as Ellipse;
                var unite = ellipse.Tag as Unite;


                int column = Grid.GetColumn(ellipse);
                int row = Grid.GetRow(ellipse);



                ellipse.Stroke = new SolidColorBrush(Colors.AliceBlue);
                ellipse.StrokeThickness = 0;
            }
            if (villeCourante != null)
            {
                var ellipse = (System.Windows.Shapes.Ellipse)formVille[villeCourante] as Ellipse;
                var unite = ellipse.Tag as Ville;


                int column = Grid.GetColumn(ellipse);
                int row = Grid.GetRow(ellipse);



                ellipse.Stroke = new SolidColorBrush(Colors.AliceBlue);
                ellipse.StrokeThickness = 0;
            }

        }

        private void cacherSelection()
        {

            updateUnitUI();
            GestionVille.Visibility = System.Windows.Visibility.Collapsed;
            GestionUnite.Visibility = System.Windows.Visibility.Collapsed;
        }
        private void afficherVilleCourante()
        {

            cacherSelectionUniteVille();
            var ellipse = (System.Windows.Shapes.Ellipse)formVille[villeCourante] as Ellipse;
            var unite = ellipse.Tag as Ville;


            int column = Grid.GetColumn(ellipse);
            int row = Grid.GetRow(ellipse);



            selectionVille.Tag = villeCourante;
            selectionVille.Visibility = System.Windows.Visibility.Visible;
            ellipse.Stroke = new SolidColorBrush(Colors.AliceBlue);
            ellipse.StrokeThickness = 1;

            Grid.SetColumn(selectionVille, column);
            Grid.SetRow(selectionVille, row);

            var selected = selectionVille.Tag;
            selectionVille.Tag = null;
            selectionVille.Tag = selected;


            GestionUnite.Visibility = System.Windows.Visibility.Collapsed;
            GestionVille.Visibility = System.Windows.Visibility.Visible;
          
            //montrerCaseSelection(villeCourante.etendue);

            resetCombo();
        }
        private void getAutresChoixJoueur()
        {
            int x = uniteCourante.position.X;
            int y = uniteCourante.position.Y;
            Joueur j = joueurCourant;
            Ville v = engine.getCarte().getVille(x, y);

            ListAutresChoix.Clear();

            foreach (Unite u in engine.getCarte().getUniteAmi(x, y, j))
            {
                ListAutresChoix.Add(u);
            }
            if (v != null && v.civilisation.joueur == j) ListAutresChoix.Add(v);
  
            ListAutresChoix.Remove(uniteCourante);
            ListAutresChoix.Insert(0, uniteCourante);
            AutresChoix.ItemsSource = null;
            AutresChoix.ItemsSource = ListAutresChoix;

            if (ListAutresChoix.Count() > 1 && (GestionUnite.Visibility == System.Windows.Visibility.Visible || GestionVille.Visibility == System.Windows.Visibility.Visible))
            {
                BoolVisibility.Tag = true;
            }
            else
            {
                BoolVisibility.Tag = false;
            }
        }
        private void getAutresChoixVille()
        {
            int x = villeCourante.position.X;
            int y = villeCourante.position.Y;
            Joueur j = joueurCourant;
            
            ListAutresChoix.Clear();

            foreach (Unite u in engine.getCarte().getUniteAmi(x, y, j))
            {
                ListAutresChoix.Add(u);
            }
            ListAutresChoix.Insert(0, villeCourante);
            AutresChoix.ItemsSource = null;
            AutresChoix.ItemsSource = ListAutresChoix;

            if (ListAutresChoix.Count() > 1 && (GestionUnite.Visibility == System.Windows.Visibility.Visible || GestionVille.Visibility == System.Windows.Visibility.Visible))
            {
                BoolVisibility.Tag = true;
            }
            else
            {
                BoolVisibility.Tag = false;
            }
        }
        private void resetCombo()
        {
            AutresChoix.SelectedItem = null;
            ChoixActionVille.SelectedItem = null;
            ChoixProductionVille.SelectedItem = null;
        }
        private void ShowError()
        {
            MyTimer timer = new MyTimer();
            timer.Tick += new EventHandler(Timer_Tick);
            timer.Interval = (1000) * (1);  // Timer will tick every second, you can change it if you want
            timer.Enabled = true;
            timer.stopTime = System.DateTime.Now.AddSeconds(3);
            timer.Start();
            MessError.Visibility = System.Windows.Visibility.Visible;
            //put your starting code here
        }
        private void ShowMessage(String mess)
        {

            MyTimer timer = new MyTimer();
            timer.Tick += new EventHandler(Timer_Tick);
            timer.Interval = (1000) * (1);  // Timer will tick every second, you can change it if you want
            timer.Enabled = true;
            timer.stopTime = System.DateTime.Now.AddSeconds(3);
            timer.Start();
            Mess.Content = mess;
            Mess.Visibility = System.Windows.Visibility.Visible;
            //put your starting code here
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            MyTimer timer = (MyTimer)sender;
            if (System.DateTime.Now >= timer.stopTime)
            {
                timer.Stop();
                Mess.Visibility = System.Windows.Visibility.Collapsed;
                MessError.Visibility = System.Windows.Visibility.Collapsed;
            }
        }

        private List<Unite> Vue()
        {
            if (joueurCourant == null) return new List<Unite>();
            List<Unite> listeVue = new List<Unite>(joueurCourant.civilisation.listeUnite);
            List<Unite> listeUniteJoueurCourant = joueurCourant.civilisation.listeUnite;
            List<Ville> listeVilleJoueurCourant = joueurCourant.civilisation.listeVille;

            foreach (Joueur j in engine.listJoueur)
            {
                if (!j.Equals(joueurCourant))
                {
                    foreach (Unite u in j.civilisation.listeUnite)
                    {
                        uniteCompare = u;
                        if (listeUniteJoueurCourant.Exists(distanceUniteUnite))
                        {
                            listeVue.Add(u);
                        }
                        else if (listeVilleJoueurCourant.Exists(distanceUniteVille))
                        {
                            listeVue.Add(u);
                        }
                    }
                }
            }

            return listeVue;
        }

        private void montrerCaseSelection(List<System.Drawing.Point> l)
        {

            cacheCaseSelection();
            if (l.Count() > 0)
            {
                affichageCaseSelection = new List<System.Drawing.Point>(l);
                foreach (System.Drawing.Point p in affichageCaseSelection)
                {
                    var position = (System.Windows.Shapes.Rectangle)formPosition[p] as Rectangle;
                    position.Stroke = Brushes.White;
                    position.StrokeThickness = 1;
                }
            }
        }
        private void cacheCaseSelection()
        {
            foreach (System.Drawing.Point p in affichageCaseSelection)
            {
                var position = (System.Windows.Shapes.Rectangle)formPosition[p] as Rectangle;
                position.Stroke = Brushes.Blue;
                position.StrokeThickness = 0;
            }

        }

        private void montrerBrouillard()
        {
            cacheBrouillard();
            affichageBrouillard.Clear();
            if (joueurCourant != null)
            {
                affichageBrouillard = new List<System.Drawing.Point>();
                foreach (Unite u in joueurCourant.civilisation.listeUnite)
                {
                    affichageBrouillard.AddRange(u.Brouillard());
                }
                foreach (Ville u in joueurCourant.civilisation.listeVille)
                {
                    affichageBrouillard.AddRange(u.Brouillard());
                }
                foreach (System.Drawing.Point p in affichageBrouillard)
                {
                    var position = (System.Windows.Shapes.Rectangle)formPosition[p] as Rectangle;
                    position.Opacity = 1;
                }
            }
        }
        private void cacheBrouillard()
        {
            foreach (System.Drawing.Point p in affichageBrouillard)
            {
                var position = (System.Windows.Shapes.Rectangle)formPosition[p] as Rectangle;
                position.Opacity = 0.3;
            }

        }
        
        


        private static bool distanceUniteVille(Ville u)
        {
            return (((Math.Abs(u.position.X - uniteCompare.position.X) + Math.Abs(u.position.Y - uniteCompare.position.Y))) <= 3);
        }
        private static bool distanceUniteUnite(Unite u)
        {
            return (((Math.Abs(u.position.X - uniteCompare.position.X) + Math.Abs(u.position.Y - uniteCompare.position.Y))) <= 2);
        }


        public unsafe List<System.Drawing.Point> suggestionVille(System.Drawing.Point p){
            List<System.Drawing.Point> l = new List<System.Drawing.Point>();
            WrapperAlgo w = new WrapperAlgo();

            int[] carte = new int[map.taille*map.taille];
            int[] positionsVilles = new int[map.taille * map.taille];

            for (int i = 0; i < map.taille; i++)
                for (int j = 0; j < map.taille; j++)
                    if ((map.getCase(i, j) is CaseFruit)||(map.getCase(i, j) is Plaine)) carte[map.taille*i+j] = 1; else carte[map.taille*i+j] = 0;
            for (int i = 0; i < map.taille; i++)
                for (int j = 0; j < map.taille; j++)
                    if (map.getVille(i, j) == null) positionsVilles[map.taille*i+j] = 0; else positionsVilles[map.taille*i+j] = 1;

            int* pointeurCarte = (int*)ArrayToIntPtr(carte);
            int* pointeurVille = (int*)ArrayToIntPtr(positionsVilles);
                      


            int* coordonnees = w.suggererCasesVilles((int*)pointeurCarte, map.taille, (int*)pointeurVille, p.X, p.Y);
            if (coordonnees[0] != -1) l.Add(new System.Drawing.Point(coordonnees[0], coordonnees[1]));
            Console.WriteLine("" + coordonnees[0] + " " + coordonnees[1] + " ");
            return l;
        }


        IntPtr ArrayToIntPtr(int[] Val)
        {
            IntPtr ret = Marshal.AllocHGlobal(Val.Length * sizeof(int));

            int offset = 0;
            for (int i = 0; i < Val.GetLength(0); i++)
            {

                Marshal.WriteInt32(ret, offset, Val[i]);
                offset += sizeof(int);            
            }

            return ret;
        }

        

    }


}





